package database

import (
	"context"
	"encoding/json"
	"github.com/go-redis/redis/v8"
	"strconv"
)

var ctx = context.Background()

// Redis  声明一个全局的redis客户端变量
type Redis struct {
	Client *redis.Client
}

var RedisClient = new(Redis)

func InitRedis() {
	// 初始化连接到redis
	RedisClient.Client = redis.NewClient(&redis.Options{
		Addr:     "192.168.0.189:6379", // redis地址
		Password: "123456",             // redis密码，没有则留空
		DB:       0,                    // 默认数据库为0
	})
}

// SaveSliceToRedis 向Redis存储切片
func (redisClient *Redis) SaveSliceToRedis(key string, slice []interface{}) error {
	// 使用pipeline批量操作以提高性能
	pipe := redisClient.Client.Pipeline()

	for _, item := range slice {
		data, err := json.Marshal(item)
		if err != nil {
			return err
		}
		pipe.RPush(ctx, key, data)
	}

	// 执行pipeline中的所有命令
	_, err := pipe.Exec(ctx)
	return err
}

// GetSliceFromRedis 从Redis读取切片
func (redisClient *Redis) GetSliceFromRedis(key string) ([]interface{}, error) {
	result, err := redisClient.Client.LRange(ctx, key, 0, -1).Result()
	if err != nil {
		return nil, err
	}

	var slice []interface{}
	for _, item := range result {
		var obj interface{}
		err := json.Unmarshal([]byte(item), &obj)
		if err != nil {
			return nil, err
		}
		slice = append(slice, obj)
	}

	return slice, nil
}

// SaveStructToRedis 将结构体保存到Redis
func (redisClient *Redis) SaveStructToRedis(key string, data interface{}) error {
	serializedData, err := json.Marshal(data)
	if err != nil {
		return err
	}
	return redisClient.Client.Set(ctx, key, serializedData, 0).Err()
}

// GetStructFromRedis 从Redis读取结构体
func (redisClient *Redis) GetStructFromRedis(key string, dest interface{}) error {
	result, err := redisClient.Client.Get(ctx, key).Result()
	if err != nil {
		return err
	}
	return json.Unmarshal([]byte(result), dest)
}

// SaveFloat64ToRedis 存储float64到Redis
func (redisClient *Redis) SaveFloat64ToRedis(key string, value float64) error {
	return redisClient.Client.Set(ctx, key, value, 0).Err()
}

// GetFloat64FromRedis 从Redis读取float64
func (redisClient *Redis) GetFloat64FromRedis(key string) (float64, error) {
	val, err := redisClient.Client.Get(ctx, key).Result()
	if err != nil {
		return 0, err
	}
	return strconv.ParseFloat(val, 64)
}

// CheckKeyExists 检查键是否存在
func (redisClient *Redis) CheckKeyExists(key string) bool {
	exists, err := redisClient.Client.Exists(ctx, key).Result()
	if err != nil {
		return false
	}
	return exists > 0
}
